home *** CD-ROM | disk | FTP | other *** search
/ Mac Magazin/MacEasy 19 / Mac Magazin and MacEasy Magazine CD - Issue 19.iso / Utilities / uae-0.4 / Source Code / hardfile.c < prev    next >
Text File  |  1996-02-13  |  9KB  |  380 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * AutoConfig devices
  5.   *
  6.   * (c) 1995 Bernd Schmidt
  7.   */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <assert.h>
  12.  
  13. #ifdef __unix
  14. #include <unistd.h>
  15. #include <fcntl.h>
  16. #endif
  17.  
  18. #include "config.h"
  19.  
  20. #ifdef __mac__
  21. #include <unix.h>
  22. #endif
  23.  
  24. #include "amiga.h"
  25. #include "options.h"
  26. #include "events.h"
  27. #include "memory.h"
  28. #include "custom.h"
  29. #include "newcpu.h"
  30. #include "disk.h"
  31. #include "xwin.h"
  32. #include "autoconf.h"
  33. #include "hardfile.h"
  34.  
  35. static int opencount = 0;
  36. static int uaedevfd;
  37. static int numtracks = 512;
  38.  
  39. static ULONG dosname, devname;
  40.  
  41. static ULONG hardfile_init(void)
  42. {
  43.     ULONG tmp1, tmp2, tmp3;
  44.     bool have36 = false;
  45.     ULONG retval = regs.d[0];
  46.  
  47.     if (!automount_uaedev)
  48.     return retval;
  49.  
  50.     regs.d[0] = 88; regs.d[1] = 1; /* MEMF_PUBLIC */
  51.     tmp1 = CallLib (regs.a[6], -198); /* AllocMem() */
  52.     if (tmp1 == 0) {
  53.     fprintf(stderr, "Not enough memory for uae.device!\n");
  54.     return 0;
  55.     }
  56.     /* Open expansion.lib */
  57.     regs.d[0] = 36; /* Let's try this... */
  58.     regs.a[1] = explibname;
  59.     regs.a[4] = CallLib (regs.a[6], -552); /* OpenLibrary() */
  60.     if (regs.a[4])
  61.     have36 = true;
  62.     else {
  63.     regs.d[0] = 0;
  64.     regs.a[1] = explibname;
  65.     regs.a[4] = CallLib (regs.a[6], -552); /* OpenLibrary() */
  66.     }
  67.     put_long (tmp1, dosname);
  68.     put_long (tmp1+4, devname);
  69.     put_long (tmp1+8, 0); /* Unit no. */
  70.     put_long (tmp1+12, 0); /* Device flags */
  71.     put_long (tmp1+16, 16); /* Env. size */
  72.     put_long (tmp1+20, 128); /* 512 bytes/block */
  73.     put_long (tmp1+24, 0); /* unused */
  74.     put_long (tmp1+28, 1); /* heads */
  75.     put_long (tmp1+32, 1); /* unused */
  76.     put_long (tmp1+36, 32); /* secs per track */
  77.     put_long (tmp1+40, 1); /* reserved blocks */
  78.     put_long (tmp1+44, 0); /* unused */
  79.     put_long (tmp1+48, 0); /* interleave */
  80.     put_long (tmp1+52, 0); /* lowCyl */
  81.     put_long (tmp1+56, 511); /* upperCyl */
  82.     put_long (tmp1+60, 0); /* Number of buffers */
  83.     put_long (tmp1+64, 0); /* Buffer mem type */
  84.     put_long (tmp1+68, 0x7FFFFFFF); /* largest transfer */
  85.     put_long (tmp1+72, ~1); /* addMask (?) */
  86.     put_long (tmp1+76, (ULONG)-1); /* bootPri */
  87.     if (have36)
  88.     put_long (tmp1+80, 0x444f5301); /* DOS\1 */
  89.     else
  90.     put_long (tmp1+80, 0x444f5300); /* DOS\0 */
  91.     
  92.     put_long (tmp1+84, 0); /* pad */
  93.     regs.a[0] = tmp1;
  94.     tmp2 = CallLib (regs.a[4], -144); /* MakeDosNode() */
  95.     regs.a[0] = tmp2;
  96.     regs.d[0] = (ULONG)-1;
  97.     regs.a[1] = 0;
  98.     regs.d[1] = 0;
  99.     CallLib (regs.a[4], -150); /* AddDosNode() */
  100. #if 0
  101. #if 0
  102.     if (have36)
  103.     CallLib (regs.a[4], /*-150*/-36); /* AddDosNode() */
  104.     else {
  105. #endif
  106.         /* We could also try to call AddBootNode() here - but we don't have
  107.      * a ConfigDev. */
  108.     regs.d[0] = 20;
  109.     regs.d[1] = 0;
  110.     tmp3 = CallLib (regs.a[6], -198);
  111.     if (tmp3 == 0) {
  112.         fprintf(stderr, "Not enough memory for uae.device bootnode!\n");
  113.         return 0;
  114.     }
  115.     put_word (tmp3 + 14, 0);
  116.     put_long (tmp3 + 16, tmp2);
  117.     put_word (tmp3 + 8, 0x1005);
  118.     put_long (tmp3 + 10, 0);
  119.     put_long (tmp3 + 0, 0);
  120.     put_long (tmp3 + 4, 0);
  121.     regs.a[0] = regs.a[4] + 74; /* MountList */
  122.     regs.a[1] = tmp3;
  123.     CallLib (regs.a[6], -270); /* Enqueue() */
  124. #if 0
  125.     }
  126. #endif
  127. #endif
  128.     
  129.     regs.a[1] = tmp1;
  130.     regs.d[0] = 88;
  131.     CallLib (regs.a[6], -210); /* FreeMem() */
  132.     
  133.     regs.a[1] = regs.a[4];
  134.     CallLib (regs.a[6], -414); /* CloseLibrary() */
  135.     
  136.     return retval;
  137. }
  138.     
  139. static ULONG hardfile_open(void)
  140. {
  141.     CPTR tmp1 = regs.a[1]; /* IOReq */
  142.     
  143.     /* Check unit number */
  144.     if (regs.d[0] == 0) {        
  145.     opencount++;
  146.     put_word (regs.a[6]+32, get_word (regs.a[6]+32) + 1);
  147.     put_long (tmp1+24, 0); /* io_Unit */
  148.     put_byte (tmp1+31, 0); /* io_Error */
  149.     put_byte (tmp1+8, 7); /* ln_type = NT_REPLYMSG */
  150.     return 0;
  151.     }
  152.  
  153.     put_long (tmp1+20, (ULONG)-1);
  154.     put_byte (tmp1+31, (UBYTE)-1);
  155.     return (ULONG)-1;
  156. }
  157.  
  158. static ULONG hardfile_close(void)
  159. {
  160.     opencount--;
  161.     put_word (regs.a[6]+32, get_word (regs.a[6]+32) - 1);
  162.  
  163.     return regs.d[0];
  164. }
  165.     
  166. static ULONG hardfile_expunge(void)
  167. {
  168.     return 0; /* Simply ignore this one... */
  169. }
  170.     
  171. static ULONG hardfile_beginio(void)
  172. {
  173.     ULONG tmp1, tmp2, dataptr, offset;
  174.     ULONG retval = regs.d[0];
  175.  
  176.     tmp1 = regs.a[1];
  177.     put_byte (tmp1+8, 5); /* set ln_type to NT_MESSAGE */
  178.     put_byte (tmp1+31, 0); /* no error yet */
  179.     tmp2 = get_word (tmp1+28); /* io_Command */
  180.     switch (tmp2) {
  181.      case 2: /* Read */
  182.     dataptr = get_long (tmp1 + 40);
  183.     if (dataptr & 1)
  184.         goto bad_command;
  185.     offset = get_long (tmp1 + 44);
  186.     if (offset & 511)
  187.         goto bad_command;
  188.     tmp2 = get_long (tmp1 + 36); /* io_Length */
  189.     if (tmp2 & 511)
  190.         goto bad_command;
  191.     if (tmp2 + offset > (ULONG)numtracks * 32 * 512)
  192.         goto bad_command;
  193.     
  194.     put_long (tmp1 + 32, tmp2); /* set io_Actual */
  195.     lseek (uaedevfd, offset, SEEK_SET);
  196.     while (tmp2) {
  197.         int i;
  198.         char buffer[512];
  199.         read (uaedevfd, buffer, 512);
  200.         for (i = 0; i < 512; i++, dataptr++)
  201.         put_byte(dataptr, buffer[i]);
  202.         tmp2 -= 512;
  203.     }
  204.     break;
  205.         
  206.      case 3: /* Write */
  207.      case 11: /* Format */
  208.     dataptr = get_long (tmp1 + 40);
  209.     if (dataptr & 1)
  210.         goto bad_command;
  211.     offset = get_long (tmp1 + 44);
  212.     if (offset & 511)
  213.         goto bad_command;
  214.     tmp2 = get_long (tmp1 + 36); /* io_Length */
  215.     if (tmp2 & 511)
  216.         goto bad_command;
  217.     if (tmp2 + offset > (ULONG)numtracks * 32 * 512)
  218.         goto bad_command;
  219.     
  220.     put_long (tmp1 + 32, tmp2); /* set io_Actual */
  221.     lseek (uaedevfd, offset, SEEK_SET);
  222.     while (tmp2) {
  223.         char buffer[512];
  224.         int i;
  225.         for (i=0; i < 512; i++, dataptr++)
  226.         buffer[i] = get_byte(dataptr);
  227.         write (uaedevfd, buffer, 512);
  228.         tmp2 -= 512;
  229.     }
  230.     break;
  231.     
  232.     bad_command:
  233.     break;
  234.     
  235.      case 18: /* GetDriveType */
  236.     put_long (tmp1 + 32, 1); /* not exactly a 3.5" drive, but... */
  237.     break;
  238.     
  239.      case 19: /* GetNumTracks */
  240.     put_long (tmp1 + 32, numtracks); 
  241.     break;
  242.     
  243.     /* Some commands that just do nothing and return zero */
  244.      case 4: /* Update */
  245.      case 5: /* Clear */
  246.      case 9: /* Motor */
  247.      case 10: /* Seek */
  248.      case 12: /* Remove */
  249.      case 13: /* ChangeNum */
  250.      case 14: /* ChangeStatus */
  251.      case 15: /* ProtStatus */
  252.      case 20: /* AddChangeInt */
  253.      case 21: /* RemChangeInt */
  254.     put_long (tmp1+32, 0); /* io_Actual */
  255.     retval = 0;
  256.     break;
  257.     
  258.      default:
  259.     /* Command not understood. */
  260.     put_byte (tmp1+31, (UBYTE)-3); /* io_Error */
  261.     retval = 0;
  262.     break;
  263.     }
  264.     if ((get_byte (tmp1+30) & 1) == 0) {
  265.     /* Not IOF_QUICK -- need to ReplyMsg */
  266.     regs.a[1] = tmp1;
  267.     CallLib (get_long(4), -378);
  268.     }
  269.     return retval;
  270. }
  271.     
  272. static ULONG hardfile_abortio(void)
  273. {
  274.     return (ULONG)-3;
  275. }
  276.  
  277. void hardfile_install(void)
  278. {
  279.     ULONG devid, functable, datatable, inittable, begin, end;
  280.     ULONG initroutine, openfunc, closefunc, expungefunc;
  281.     ULONG nullfunc, beginiofunc, abortiofunc;
  282.  
  283.     uaedevfd = open ("hardfile", O_RDWR);
  284.     
  285.     if (uaedevfd < 0)
  286.         return;
  287.     
  288.     devname = ds("uae.device");
  289.     devid = ds("uae 0.4"); /* ID */
  290.     dosname = ds("UAEHF"); /* This is the DOS name */
  291.  
  292.     begin = here();
  293.     dw(0x4AFC); /* RTC_MATCHWORD */
  294.     dl(begin); /* our start address */
  295.     dl(0); /* Continue scan here */
  296.     dw(0x8101); /* RTF_AUTOINIT|RTF_COLDSTART; Version 1 */
  297.     dw(0x0305); /* NT_DEVICE; pri 5 */
  298.     dl(devname); /* name */
  299.     dl(devid); /* ID */
  300.     dl(here() + 4); /* Init area: directly after this */
  301.     /* Init area starts here */
  302.     dw(0x0000); /* Not really sure what to put here */
  303.     dw(0x0100);
  304.     inittable = here();
  305.     dl(0); dl(0); dl(0); /* skip 3 longs */
  306.  
  307.     /* InitRoutine */
  308.     initroutine = here();
  309.     calltrap(deftrap(hardfile_init)); dw(RTS);
  310.  
  311.     /* Open */
  312.     openfunc = here();
  313.     calltrap(deftrap(hardfile_open)); dw(RTS);
  314.  
  315.     /* Close */
  316.     closefunc = here();
  317.     calltrap(deftrap(hardfile_close)); dw(RTS);
  318.  
  319.     /* Expunge */
  320.     expungefunc = here();
  321.     calltrap(deftrap(hardfile_expunge)); dw(RTS);
  322.     
  323.     /* Null */
  324.     nullfunc = here();
  325.     dw(0x7000); /* return 0; */
  326.     dw(RTS);
  327.  
  328.     /* BeginIO */
  329.     beginiofunc = here();
  330.     calltrap(deftrap(hardfile_beginio)); dw(RTS);
  331.  
  332.     /* AbortIO */
  333.     abortiofunc = here();
  334.     calltrap(deftrap(hardfile_abortio)); dw(RTS);
  335.     
  336.     /* FuncTable */
  337.     functable = here();
  338.     dl(openfunc); /* Open */
  339.     dl(closefunc); /* Close */
  340.     dl(expungefunc); /* Expunge */
  341.     dl(nullfunc); /* Null */
  342.     dl(beginiofunc); /* BeginIO */
  343.     dl(abortiofunc); /* AbortIO */
  344.     dl(0xFFFFFFFF); /* end of table */
  345.  
  346.     /* DataTable */
  347.     datatable = here();
  348.     dw(0xE000); /* INITBYTE */
  349.     dw(0x0008); /* LN_TYPE */
  350.     dw(0x0300); /* NT_DEVICE */
  351.     dw(0xC000); /* INITLONG */
  352.     dw(0x000A); /* LN_NAME */
  353.     dl(devname);
  354.     dw(0xE000); /* INITBYTE */
  355.     dw(0x000E); /* LIB_FLAGS */
  356.     dw(0x0600); /* LIBF_SUMUSED | LIBF_CHANGED */
  357.     dw(0xD000); /* INITWORD */
  358.     dw(0x0014); /* LIB_VERSION */
  359.     dw(0x0004); /* 0.4 */
  360.     dw(0xD000);
  361.     dw(0x0016); /* LIB_REVISION */
  362.     dw(0x0000);
  363.     dw(0xC000);
  364.     dw(0x0018); /* LIB_IDSTRING */
  365.     dl(devid);
  366.     dw(0x0000); /* end of table */
  367.  
  368.     end = here();
  369.  
  370.     org(inittable);
  371.     dl(functable);
  372.     dl(datatable);
  373.     dl(initroutine);
  374.  
  375.     org(begin + 6);
  376.     dl(end);
  377.  
  378.     org(end);
  379. }
  380.